/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.nys.conci.citas.servicio;

import com.nys.conci.base.ServicioBase;
import com.nys.conci.base.excepcion.ExcepcionServicio;
import com.nys.conci.citas.entidad.ControlCita;
import com.nys.conci.cliente.entidad.Pago;
import com.nys.conci.cliente.entidad.PlanCliente;
import com.nys.conci.cliente.entidad.PlanPago;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.Query;

/**
 * Clase Servicio que se contiene la lógica del negocio relacionada con las
 * citas. Contiene los métodos que acceden a la capa de persistencia, y
 * funciones con lógica del negocio.
 *
 * @author Yeudy10
 * @since 13/02/2013
 */
@Stateless
@TransactionAttribute(value = TransactionAttributeType.REQUIRED)
public class ServicioControlCitas extends ServicioBase {

    /**
     * Método que guarda o actualiza una cita
     *
     * @param esp Objeto de tipo ControlCita
     * @param modificar parámetro que indica si se va actualizar o guardar
     * @return El objeto que se guardo
     */
    public ControlCita guardarCita(ControlCita cita, boolean modificar) {
        try {
            if (modificar) {
                actualizar(cita);
            } else {
                guardar(cita);
            }
            return cita;
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error al guardar la especialida",
                    "Ha ocurrido un error al guardar la especialida. En " + getClass() + ".guardarCita(ControlCita cita, boolean modificar)",
                    ex, getClass());
        }
    }
    

    /**
     * Método que consulta una lista de citas antiguas
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasAntiguas(Date fecha, Integer id_plan, Integer id_estado, Integer id_especialidad) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String cons = "";
            if (fecha != null) {
                cons = " and c.fechareal = :fecha";
            }

            if (id_estado != null && id_estado != 0) {
                cons = cons + " and c.id_estado_cita = :estado";
            }

            if (id_plan != null && id_plan != 0) {
                cons = cons + " and c.id_plan_cliente = :plan";
            }

            if (id_especialidad != null && id_especialidad != 0) {
                cons = cons + " and c.id_especialidad =  :id_especialidad";
            }

            String consulta = "SELECT c.* FROM control_cita c where c.fechareal < CURRENT_DATE " + cons;

            Query q = em.createNativeQuery(consulta, ControlCita.class);


            if (fecha != null) {
                q.setParameter("fecha", fecha);
            }

            if (id_estado != null && id_estado != 0) {
                q.setParameter("estado", id_estado);
            }

            if (id_plan != null && id_plan != 0) {
                q.setParameter("plan", id_plan);
            }

            if (id_especialidad != null && id_especialidad != 0) {
                q.setParameter("id_especialidad", id_especialidad);
            }

            lista = q.getResultList();
            return lista;


        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarListaCitasAntiguas()",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de pagos realizado por un cliente
     *
     * @return Lista de Pagos
     */
    public List<Pago> consultarListaPagosCliente(String id, Integer id_plan_pago) {
        try {
            List<Pago> lista = new ArrayList<Pago>();
            String cons = "";
            if (id_plan_pago != null && id_plan_pago != 0) {
                cons = " and id_plan_pago = :id_plan_pago";
            }
            String consulta = "select p.* from pago p "
                    + "where "
                    + "p.identificacion = :id " + cons;

            Query q = em.createNativeQuery(consulta, Pago.class).setParameter("id", id);
            if (id_plan_pago != null && id_plan_pago != 0) {
                q.setParameter("id_plan_pago", id_plan_pago);
            }

            lista = q.getResultList();

            return lista;
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de pagos",
                    "Ha ocurrido un error obteniendo el listado de pagos. En " + getClass() + ".consultarListaPagosCliente(String id, Integer id_plan_pago)",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de citas antiguas
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasId(String identificacion_c) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "SELECT c FROM ControlCita c where identificacion_c = :identificacion_c order by fechareal desc,hora asc";

            lista = em.createQuery(consulta, ControlCita.class).setParameter("identificacion_c", identificacion_c).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarListaCitasId(String identificacion_c)",
                    ex, getClass());
        }
    }
    
    
    /**
     * Método que consulta una lista de citas antiguas
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasIdActFut(String identificacion_c) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "SELECT c.* FROM control_cita c where c.identificacion_c = :identificacion_c and c.fechareal >= CURRENT_DATE "
                    + "order by fechareal desc,hora asc";

            lista = em.createNativeQuery(consulta, ControlCita.class).setParameter("identificacion_c", identificacion_c).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarListaCitasId(String identificacion_c)",
                    ex, getClass());
        }
    }    

    /**
     * Método que consulta una lista de citas antiguas
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListasCitasUsuario(String identificacion_u) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "SELECT c FROM ControlCita c where identificacion_u = :identificacion_u order by fechareal desc,hora asc";

            lista = em.createQuery(consulta, ControlCita.class).setParameter("identificacion_u", identificacion_u).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarListaCitasId(String identificacion_c)",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de citas actuales correspondientes a un
     * usuario
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasUsuario(String identificacion_u) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "select cc.* from control_cita cc, estado_cita ec where cc.identificacion_u = :identificacion_u and "
                    + "cc.id_estado_cita = ec.id_estado_cita and ec.nombre = 'En espera' and cc.fechareal = CURRENT_DATE";

            lista = em.createNativeQuery(consulta, ControlCita.class).setParameter("identificacion_u", identificacion_u).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarListaCitasId(String identificacion_u)",
                    ex, getClass());
        }
    }
    
    
    /**
     * Método que consulta una lista de citas actuales correspondientes a un
     * cliente con la fecha actual
     *
     * @return Lista de citas
     */
    public List<ControlCita> consultarListaCitasCliente(String identificacion_c) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "select cc.* from control_cita cc where cc.identificacion_c = :identificacion_c and "
                    + " cc.fechareal = CURRENT_DATE";

            lista = em.createNativeQuery(consulta, ControlCita.class).setParameter("identificacion_c", identificacion_c).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + 
                    ".consultarListaCitasCliente(String identificacion_c)",
                    ex, getClass());
        }
    }    
     

    /**
     * Método que consulta un plan cliente utilizado en un control de citas
     *
     * @return Lista de ControlCita
     */
    public List<ControlCita> consultarPlanUsado(Integer id_plan_cliente) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String consulta = "SELECT c FROM ControlCita c where id_plan_cliente = :id_plan_cliente";

            lista = em.createQuery(consulta, ControlCita.class).setParameter("id_plan_cliente", id_plan_cliente).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass() + ".consultarPlanUsado(Integer id_plan_cliente)",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de planes de clientes
     *
     * @return Lista de planes de clientes
     */
    public List<PlanCliente> consultarListaPlanCienteId(String identificacion_c) {
        try {

            List<PlanCliente> lista = new ArrayList<PlanCliente>();

            String consulta = "SELECT c FROM PlanCliente c where identificacion_c = :identificacion_c";

            lista = em.createQuery(consulta, PlanCliente.class).setParameter("identificacion_c", identificacion_c).getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de planes de cliente",
                    "Ha ocurrido un error obteniendo el listado de planes de cliente. En " + getClass() + ".consultarListaPlanCienteId(String identificacion_c)",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de citas actuales
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasActuales(Integer id_plan, Integer id_estado, Integer id_especialidad) {
        try {

            List<ControlCita> lista = new ArrayList<ControlCita>();

            String cons = "";
            if (id_estado != null && id_estado != 0) {
                cons = cons + " and c.id_estado_cita =  :estado";
            }

            if (id_plan != null && id_plan != 0) {
                cons = cons + " and c.id_plan_cliente =  :plan";
            }
            if (id_especialidad != null && id_especialidad != 0) {
                cons = cons + " and c.id_especialidad =  :id_especialidad";
            }

            String consulta = "SELECT c.* FROM control_cita c  where fechareal = CURRENT_DATE " + cons;

            Query q = em.createNativeQuery(consulta, ControlCita.class);


            if (id_estado != null && id_estado != 0) {
                q.setParameter("estado", id_estado);
            }

            if (id_plan != null && id_plan != 0) {
                q.setParameter("plan", id_plan);
            }
            if (id_especialidad != null && id_especialidad != 0) {
                q.setParameter("id_especialidad", id_especialidad);
            }

            lista = q.getResultList();
            return lista;

        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de control de citas actuales",
                    "Ha ocurrido un error obteniendo el listado listado de control de citas actuales. En " + getClass()
                    + ".consultarListaCitasActuales(Integer id_plan, Integer id_estado)",
                    ex, getClass());
        }
    }

    /**
     * Método que consulta una lista de citas proximas
     *
     * @return Lista de especialidades
     */
    public List<ControlCita> consultarListaCitasProximas(Date fecha, Integer id_plan, Integer id_estado, Integer id_especialidad) {
        try {
            List<ControlCita> lista = new ArrayList<ControlCita>();

            String cons = "";
            if (fecha != null) {
                cons = " and c.fechareal = :fecha";
            }

            if (id_estado != null && id_estado != 0) {
                cons = cons + " and c.id_estado_cita =  :estado";
            }

            if (id_plan != null && id_plan != 0) {
                cons = cons + " and c.id_plan_cliente =  :plan";
            }

            if (id_especialidad != null && id_especialidad != 0) {
                cons = cons + " and c.id_especialidad =  :id_especialidad";
            }

            String consulta = "SELECT * FROM control_cita c where fechareal > CURRENT_DATE " + cons;

            Query q = em.createNativeQuery(consulta, ControlCita.class);


            if (fecha != null) {
                q.setParameter("fecha", fecha);
            }

            if (id_estado != null && id_estado != 0) {
                q.setParameter("estado", id_estado);
            }

            if (id_plan != null && id_plan != 0) {
                q.setParameter("plan", id_plan);
            }

            if (id_especialidad != null && id_especialidad != 0) {
                q.setParameter("id_especialidad", id_especialidad);
            }



            lista = q.getResultList();
            return lista;
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de especialidades",
                    "Ha ocurrido un error obteniendo el listado de especialidades. En " + getClass()
                    + ".consultarListaCitasProximas(Date fecha, Integer id_plan, Integer id_estado)",
                    ex, getClass());
        }
    }

    public List<ControlCita> consultaListaActualesProximas() {
        List<ControlCita> lista = new ArrayList<ControlCita>();
        try {
            String consulta = "SELECT * FROM control_cita c where fechareal >= CURRENT_DATE  order by fechareal asc, hora desc";
            Query q = em.createNativeQuery(consulta, ControlCita.class);
            lista = q.getResultList();
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas",
                    "Ha ocurrido un error obteniendo el listado de citas. En " + getClass()
                    + ".consultaListaActualesProximas()",
                    ex, getClass());
        }
        return lista;
    }

    public List<ControlCita> consultaListaCitasUsuario(String identificacion_u) {
        List<ControlCita> lista = new ArrayList<ControlCita>();
        try {
            String consulta = "SELECT * FROM control_cita c where identificacion_u=:identificacion_u and fechareal >= CURRENT_DATE  order by fechareal asc, hora desc";
            Query q = em.createNativeQuery(consulta, ControlCita.class);
            q.setParameter("identificacion_u", identificacion_u);
            lista = q.getResultList();
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas por identificacion del usuario",
                    "Ha ocurrido un error obteniendo el listado de citas por identificacion del usuario. En " + getClass()
                    + ".consultaListaCitasUsuario(String identificacion_u)",
                    ex, getClass());
        }
        return lista;
    }

    public List<ControlCita> consultaListaCitasUsuario(String identificacion_u, Date fecha, String tipo_pago) {
        List<ControlCita> lista = new ArrayList<ControlCita>();
        try {
            String cons = "";
            if (tipo_pago != null && !tipo_pago.isEmpty()) {
                cons = " and tipo_pago = :tipo_pago";
            }
            if (fecha != null) {
                cons = cons + " and p.fecha = :fecha";
            }

            if (identificacion_u != null && !identificacion_u.isEmpty()) {
                cons = cons + " and c.identificacion_u = :identificacion_u";
            }

            String consulta = "select c.* from control_cita c, pago p where c.id_cita = p.id_cita " + cons + "  order by c.fechareal asc, c.hora desc";
            Query q = em.createNativeQuery(consulta, ControlCita.class);
            if (tipo_pago != null && !tipo_pago.isEmpty()) {
                q.setParameter("tipo_pago", tipo_pago);
            }
            if (fecha != null) {
                q.setParameter("fecha", fecha);
            }

            if (identificacion_u != null && !identificacion_u.isEmpty()) {
                q.setParameter("identificacion_u", identificacion_u);
            }

            lista = q.getResultList();
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas por identificacion del usuario",
                    "Ha ocurrido un error obteniendo el listado de citas por identificacion del usuario. En " + getClass()
                    + ".consultaListaCitasUsuario(String identificacion_u, Date fecha, String tipo_pago)",
                    ex, getClass());
        }
        return lista;
    }

    public List<ControlCita> consultaListaCitasoEspecialidad(Integer id_especialidad) {
        List<ControlCita> lista = new ArrayList<ControlCita>();
        try {
            String consulta = "SELECT * FROM control_cita c where id_especialidad=:id_especialidad ";
            Query q = em.createNativeQuery(consulta, ControlCita.class);
            q.setParameter("id_especialidad", id_especialidad);
            lista = q.getResultList();
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas por id de especialidad",
                    "Ha ocurrido un error obteniendo el listado de citas por id de especialidad. En " + getClass()
                    + ".consultaListaCitasUsuarioEspecialidad(Integer id_especialidad)",
                    ex, getClass());
        }
        return lista;
    }

    public List<ControlCita> consultaListaCitasIdEstado(Integer id_estado_cita) {
        List<ControlCita> lista = new ArrayList<ControlCita>();
        try {
            String consulta = "SELECT * FROM control_cita c where id_estado_cita=:id_estado_cita ";
            Query q = em.createNativeQuery(consulta, ControlCita.class);
            q.setParameter("id_estado_cita", id_estado_cita);
            lista = q.getResultList();
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo el listado de citas por id de estado",
                    "Ha ocurrido un error obteniendo el listado de citas por id de estado. En " + getClass()
                    + ".consultaListaCitasIdEstado(Integer id_estado_cita)",
                    ex, getClass());
        }
        return lista;
    }

    public PlanPago consultarPlanPagoCliente(Integer id_plan_cliente) {
        List<PlanPago> lista = new ArrayList<PlanPago>();
        try {
            String consulta = "SELECT pp.* FROM plan_pago pp, plan_cliente pc where pc.id_plan_pago = pp.id_plan_pago and pc.id_plan_cliente = :id_plan_cliente";
            Query q = em.createNativeQuery(consulta, PlanPago.class).setParameter("id_plan_cliente", id_plan_cliente);
            lista = q.getResultList();
            if (lista == null || lista.isEmpty()) {
                return null;
            }
        } catch (Exception ex) {
            throw new ExcepcionServicio("Ha ocurrido un error obteniendo un plan de pago",
                    "Ha ocurrido un error obteniendo un plan de pago. En " + getClass()
                    + ".consultarPlanPagoCliente(Integer id_plan_cliente)",
                    ex, getClass());
        }
        return lista.get(0);
    }
}
